<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>事件循环机制</title>
  </head>
  <body>
    <script>
      /*
        JS引擎主线程将所有js代码放入执行栈中依次执行，遇到同步代码从上到下依次执行
        遇到异步代码，将任务交给浏览器分线程管理模块去执行，JS引擎主线程会继续剩下代码
          例如：
            1. JS引擎主线程遇到定时器代码，交给浏览器定时器管理模块计时，当定时器到点，
              浏览器定时器管理模块会将回调函数放入宏任务队列等待执行
            2. JS引擎主线程遇到DOM事件代码，交给浏览器DOM事件管理模块绑定事件，等用户触发事件，
              将回调函数放入宏任务队列等待执行

            宏任务：
              1. 定时器（setTimeout/setInterval）
              2. DOM事件
              3. ajax

            微任务：
              1. Promise.then/catch/finally
              2. async await
              3. MutationObserver（监视DOM元素变化，一旦发生变化就会执行某个回调）

        等JS引擎主线程执行完全局所有代码，此时就会开启事件轮询（event loop）
          1. 取出微任务队列中回调函数，依次执行
          2. 等微任务队列中回调函数全部执行完毕，取出宏任务队列中第一个回调函数，执行
          3. 等宏任务队列中第一个回调函数执行完毕，继续依次执行微任务队列中所有回调函数
          4. 等微任务队列中回调函数全部执行完毕，取出宏任务队列中下一个回调函数，执行
          5. 等宏任务队列中第一个回调函数执行完毕，继续依次执行微任务队列中所有回调函数
          6. 以此反复
    */

      console.log(1);

      setTimeout(() => {
        console.log(2);

        Promise.resolve().then(() => {
          console.log(3);
        });
      }, 0);

      Promise.resolve().then(() => {
        console.log(4);

        setTimeout(() => {
          console.log(5);
        }, 0);
      });

      console.log(6);
    </script>
  </body>
</html>
